import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:im_app/im/dao/ImMessageDao.dart';
import 'package:im_app/im/pojo/ImPojo.dart';
import 'package:im_app/im/util/DbUtil.dart';

import '../../pojo/Enums.dart';

final class MessageHistoryCubit extends Bloc<MessageHistoryEvent, MessageHistoryState> {
  MessageHistoryCubit() : super(MessageHistoryState.loading()) {
    on<MessageHistoryInitEvent>((event, emit){
      _init(this.state, event.sessionId);
    });
    on<MessageHistoryTypeEvent>((event, emit){
      _selectMessageTypes(this.state, event.prefix, event.messageTypes);
    });

    on<MessageHistorySearchEvent>((event, emit){
      _search(this.state, event.search);
    });
  }

  _init(MessageHistoryState oldState, int sessionId) {
    var newState = MessageHistoryState.init(sessionId);
    emit(newState);
  }

  _selectMessageTypes(MessageHistoryState oldState, String prefix, List<ImMessageType> messageTypes) async {
    var messageDao = ImMessageDao();
    var messages = await messageDao.getBySessionIdAndTypes(oldState.sessionId, oldState.search, null, messageTypes,
        500, true);

    var newState = oldState.copy(prefix: prefix, messageTypes: messageTypes, results: messages);
    emit(newState);
  }

  _search(MessageHistoryState oldState, String search) async {
    var messageDao = ImMessageDao();
    var messages = await messageDao.getBySessionIdAndTypes(oldState.sessionId, search, null,
        oldState.messageTypes, 500, true);
    var newState =  oldState.copy(results: messages, search: search);
    emit(newState);
  }
}

final class MessageHistoryState extends Equatable {

  final LoadingState state;
  final String prefix;
  final String search;
  final List<ImMessageType> messageTypes;
  final List<ImMessage> results;
  final int sessionId;

  const MessageHistoryState._({
    this.state = LoadingState.loading,
    this.prefix = '',
    this.search = '',
    this.messageTypes = const <ImMessageType>[],
    this.results = const <ImMessage>[],
    this.sessionId = -1,
  });

  MessageHistoryState copy({String? prefix, String? search, List<ImMessageType>? messageTypes, List<ImMessage>?
    messages, LoadingState? state, List<ImMessage>? results}) {
      return MessageHistoryState._(
        state: state ?? this.state,
        prefix: prefix ?? this.prefix,
        search: search ?? this.search,
        messageTypes: messageTypes ?? this.messageTypes,
        results: results ?? this.results,
        sessionId: this.sessionId,
      );
  }

  const MessageHistoryState.loading() : this._();

  const MessageHistoryState.init(int sessionId)
      : this._(state: LoadingState.success, sessionId: sessionId);

  const MessageHistoryState.failure() : this._(state: LoadingState.failure);

  @override
  List<Object?> get props => [state, prefix, search, messageTypes, results, sessionId];

}

class MessageHistoryEvent {}
class MessageHistoryTypeEvent extends MessageHistoryEvent {
  String prefix;
  List<ImMessageType> messageTypes;

  MessageHistoryTypeEvent(this.prefix, this.messageTypes);
}
class MessageHistorySearchEvent extends MessageHistoryEvent {
  String search;
  MessageHistorySearchEvent(this.search);
}
class MessageHistoryInitEvent extends MessageHistoryEvent {
  int sessionId;
  MessageHistoryInitEvent(this.sessionId);
}